﻿/* 2014/1/11 */
using System.IO;
using System.Security.Cryptography;

namespace Cosmos.Security.Cryptography
{
    /// <summary>
    /// Calculates hash value of file.
    /// </summary>
    public static class FileHashCalculator
    {
        /// <summary>
        /// Calculates hash values of a file.
        /// </summary>
        /// <param name="filePath">The path of file.</param>
        /// <returns>HashValue of the file.</returns>
        /// <exception cref="FileNotFoundException">The file does not exist.</exception>
        public static HashValue HashFile(string filePath)
        {
            if (!File.Exists(filePath))
                throw new FileNotFoundException("The specified file does not exist.");

            byte[] md5Value;
            HashAlgorithm md5 = new MD5CryptoServiceProvider();
            FileStream fs_md5 = new FileStream(filePath, FileMode.Open);
            md5Value = md5.ComputeHash(fs_md5);
            fs_md5.Close();

            byte[] sha1Value;
            HashAlgorithm sha1 = new SHA1CryptoServiceProvider();
            FileStream fs_sha1 = new FileStream(filePath, FileMode.Open);
            sha1Value = sha1.ComputeHash(fs_sha1);
            fs_sha1.Close();

            byte[] crc32Value;
            FileStream fs_crc32 = new FileStream(filePath, FileMode.Open);
            crc32Value = CRC32.ComputeHash(fs_crc32);
            fs_crc32.Close();

            return new HashValue(md5Value, sha1Value, crc32Value);
        }

        /// <summary>
        /// Calculates hash values of files.
        /// </summary>
        /// <param name="files">An array of instances of FileInfo class.</param>
        /// <returns>An array of HashValue of the files.</returns>
        public static HashValue[] HashFiles(FileInfo[] files)
        {
            int count = files.Length;
            HashValue[] result = new HashValue[count];

            for (int i = 0; i < count; i++)
            {
                result[i] = HashFile(files[i].FullName);
            }

            return result;
        }
    }
}
